package com.jctrip.hotel.management.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jctrip.hotel.common.util.BeanUtil;
import com.jctrip.hotel.domain.dao.*;
import com.jctrip.hotel.domain.entity.*;
import com.jctrip.hotel.management.model.param.*;
import com.jctrip.hotel.management.model.result.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class RouteInfoService {

    @Autowired
    private HtRouteInfoDao htRouteInfoDao;

    @Autowired
    private HtHotelStdInfoDao htHotelStdInfoDao;

    @Autowired
    private HtPriceCalendarDao htPriceCalendarDao;

    @Autowired
    private HtPricePolicyDao htPricePolicyDao;

    @Autowired
    private HtRouteCodeDao htRouteCodeDao;

    public GetRouteCodeResult listRouteCode(){
        List<HtRouteCode> htRouteCodes = htRouteCodeDao.selectList(new LambdaQueryWrapper<>());
        List<GetRouteCodeResult.RouteCodeInfo> routeCodeInfoList = new ArrayList<>();
        for (HtRouteCode htRouteCode : htRouteCodes) {
            GetRouteCodeResult.RouteCodeInfo routeCodeInfo = GetRouteCodeResult.RouteCodeInfo.builder().build();
            BeanUtil.copyProperties(htRouteCode,routeCodeInfo);
            routeCodeInfoList.add(routeCodeInfo);
        }
        return GetRouteCodeResult.builder().routeCodeInfoList(routeCodeInfoList).build();
    }

    public GetRouteNameResult listName(GetRouteNameParam param){
        List<HtRouteInfo> htRouteInfos = htRouteInfoDao.selectList(new LambdaQueryWrapper<HtRouteInfo>()
                .select(HtRouteInfo::getContactEmail,HtRouteInfo::getContactTel,HtRouteInfo::getId,
                        HtRouteInfo::getRouteCode,HtRouteInfo::getRouteId,HtRouteInfo::getRouteName));
        List<GetRouteNameResult.RouteInfo> routeInfoList = htRouteInfos.stream()
                .map(item->{
                    GetRouteNameResult.RouteInfo routeInfo = GetRouteNameResult.RouteInfo.builder().build();
                    BeanUtil.copyProperties(item, routeInfo);
                    return routeInfo;
                }).collect(Collectors.toList());
        if(StringUtils.isNotBlank(param.getRouteCode())){
            routeInfoList = routeInfoList.stream()
                    .filter(routeInfo -> routeInfo.getRouteCode().equals(param.getRouteCode())).collect(Collectors.toList());
        }
        return GetRouteNameResult.builder()
                .routeInfoList(routeInfoList)
                .build();
    }

    public GetHotelListResult listhotels(GetHotelListParam param){
        if(StringUtils.isBlank(param.getRouteId()) || StringUtils.isBlank(param.getCityName()) ||
                StringUtils.isBlank(param.getArriveDate()) || StringUtils.isBlank(param.getDepartDate())){
            throw new RuntimeException("参数有误");
        }
        if(param.getLowPrice() == null || param.getHighPrice() == null || param.getHighPrice().compareTo(param.getLowPrice()) < 0){
            throw new RuntimeException("参数有误");
        }
        LambdaQueryWrapper<HtPricePolicy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HtPricePolicy::getRouteId, param.getRouteId());
        queryWrapper.eq(HtPricePolicy::getPricePolicyStatus, 1);
        // 价格政策配置
        List<HtPricePolicy> htPricePolicies = htPricePolicyDao.selectList(queryWrapper);
        if(CollectionUtils.isEmpty(htPricePolicies)){
            return null;
        }
        List<String> sourceCodes = htPricePolicies.stream()
                .map(HtPricePolicy::getSourceCode)
                .collect(Collectors.toList());
        List<String> collect = htHotelStdInfoDao.selectList(new LambdaQueryWrapper<HtHotelStdInfo>()
                .in(HtHotelStdInfo::getSourceCode, sourceCodes).eq(HtHotelStdInfo::getCityName, param.getCityName())
                .select(HtHotelStdInfo::getHotelId)).stream().map(HtHotelStdInfo::getHotelId).collect(Collectors.toList());
        List<GetHotelListResult.HotelInfo> hotelInfos = new ArrayList<>();
        try {
            Date departDate = new SimpleDateFormat("yyyy-MM-dd").parse(param.getDepartDate());
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(departDate);
            calendar.add(Calendar.DAY_OF_MONTH, -1);
            departDate = calendar.getTime();
            String format = new SimpleDateFormat("yyyy-MM-dd").format(departDate);
            List<HtPriceCalendar> htPriceCalendars = htPriceCalendarDao.selectList(new QueryWrapper<HtPriceCalendar>()
                    .in("hotel_id", collect)
                    .ge("cal_date", param.getArriveDate()).le("cal_date", format)
                    .groupBy("hotel_id", "room_type_code")
                    .select("hotel_id", "room_type_code", "sum(retail_price) as retail_price"));
            htPriceCalendars.forEach(item -> {
                if(item.getRetailPrice().compareTo(param.getHighPrice()) <= 0 && param.getLowPrice().compareTo(item.getRetailPrice()) <= 0)
                {
                    GetHotelListResult.HotelInfo info = new GetHotelListResult.HotelInfo();
                    info.setHotelId(item.getHotelId());
                    info.setRoomTypeCode(item.getRoomTypeCode());
                    info.setTotalPrice(item.getRetailPrice());
                    hotelInfos.add(info);
                }
            });
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return GetHotelListResult.builder().hotelsList(hotelInfos).build();
    }

    public GetAllRouteListResult listAllRoutes(String route_code, String name, Long pageNo, Long pageSize){
        LambdaQueryWrapper<HtRouteInfo> htRouteInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        if(StringUtils.isNotBlank(route_code)){
            htRouteInfoLambdaQueryWrapper.eq(HtRouteInfo::getRouteCode, route_code);
        }
        if(StringUtils.isNotBlank(name)){
            htRouteInfoLambdaQueryWrapper.like(HtRouteInfo::getRouteName, name);
        }
        Page<HtRouteInfo> htRouteInfoPage = new Page<>();
        htRouteInfoPage.setSize(pageSize);
        htRouteInfoPage.setCurrent(pageNo);
        Page<HtRouteInfo> routeInfoPage = htRouteInfoDao.selectPage(htRouteInfoPage, htRouteInfoLambdaQueryWrapper);

        List<GetAllRouteListResult.RouteInfo> routeInfoList = new ArrayList<>();

        routeInfoPage.getRecords().forEach(htRouteInfo -> {
            GetAllRouteListResult.RouteInfo routeInfo = GetAllRouteListResult.RouteInfo.builder().build();
            BeanUtil.copyProperties(htRouteInfo, routeInfo);
            routeInfo.setId(String.valueOf(htRouteInfo.getId()));
            routeInfo.setChannelType(Optional.ofNullable(htRouteCodeDao.selectOne(new LambdaQueryWrapper<HtRouteCode>()
                    .eq(HtRouteCode::getCode, htRouteInfo.getRouteCode())))
                    .orElse(new HtRouteCode())
                    .getName());
            routeInfo.setUserName(htRouteInfo.getRouteName());
            routeInfo.setAppId(htRouteInfo.getRouteId());
            routeInfo.setSecretKey(htRouteInfo.getRouteSecret());
            routeInfo.setTel(htRouteInfo.getContactTel());
            routeInfo.setSellerType(htRouteInfo.getRouteType());
            routeInfo.setStatus(htRouteInfo.getRouteStatus());
            routeInfo.setEmail(htRouteInfo.getContactEmail());
            routeInfoList.add(routeInfo);
        });

        return GetAllRouteListResult.builder()
                .current(routeInfoPage.getCurrent())
                .size(routeInfoPage.getSize())
                .total(routeInfoPage.getTotal())
                .pages(routeInfoPage.getPages())
                .records(routeInfoList)
                .build();
    }

    public String editRouteInfo(UpdateRouteInfoParam param){
        if(StringUtils.isBlank(param.getId())){
            throw new RuntimeException("主键不能为空");
        }
        if(StringUtils.isBlank(param.getRouteCode())){
            throw new RuntimeException("渠道不能为空");
        }
        if(StringUtils.isBlank(param.getUserName())){
            throw new RuntimeException("渠道名不能为空");
        }
        if(StringUtils.isBlank(param.getAppId())){
            throw new RuntimeException("渠道账户id不能为空");
        }
        if(StringUtils.isBlank(param.getSecretKey())){
            throw new RuntimeException("渠道账户秘钥不能为空");
        }
        if(StringUtils.isBlank(param.getTel())){
            throw new RuntimeException("联系电话不能为空");
        }
        if(null == param.getSellerType()){
            throw new RuntimeException("渠道类型不能为空");
        }
        if(null == param.getStatus()){
            throw new RuntimeException("渠道状态不能为空");
        }
        if(null == param.getPriceType()){
            throw new RuntimeException("价格模式不能为空");
        }
        if(null == param.getAutoOrderSwitch()){
            throw new RuntimeException("自动处理订单开关不能为空");
        }
        /// 后续再说
//        if(null == param.getAutoOrderPriceMin()){
//            throw new RuntimeException("自动处理订单价格区间最低值不能为空");
//        }
//        if(null == param.getAutoOrderPriceMax()){
//            throw new RuntimeException("自动处理订单价格区间最高值不能为空");
//        }
        if(null == param.getAccountCredit()){
            throw new RuntimeException("账户额度不能为空");
        }
        if(null == param.getMinimum()){
            throw new RuntimeException("账户额度预警不能为空");
        }
        HtRouteInfo htRouteInfo = new HtRouteInfo();
        BeanUtil.copyProperties(param, htRouteInfo);
        htRouteInfo.setId(Long.valueOf(param.getId()));
        htRouteInfo.setRouteName(param.getUserName());
        htRouteInfo.setRouteId(param.getAppId());
        htRouteInfo.setRouteSecret(param.getSecretKey());
        htRouteInfo.setContactTel(param.getTel());
        htRouteInfo.setRouteType(param.getSellerType());
        htRouteInfo.setRouteStatus(param.getStatus());
        htRouteInfo.setContactEmail(param.getEmail());
        return htRouteInfoDao.updateById(htRouteInfo) == 1 ? "编辑成功!" : "编辑失败!";
    }

    public String addRouteInfo(InsertRouteInfoParam param){
        if(StringUtils.isBlank(param.getRouteCode())){
            throw new RuntimeException("渠道不能为空");
        }
        if(StringUtils.isBlank(param.getUserName())){
            throw new RuntimeException("渠道名不能为空");
        }
        if(StringUtils.isBlank(param.getAppId())){
            throw new RuntimeException("渠道账户id不能为空");
        }
        if(StringUtils.isBlank(param.getSecretKey())){
            throw new RuntimeException("渠道账户秘钥不能为空");
        }
        if(StringUtils.isBlank(param.getTel())){
            throw new RuntimeException("联系电话不能为空");
        }
        if(null == param.getSellerType()){
            throw new RuntimeException("渠道类型不能为空");
        }
        if(null == param.getStatus()){
            throw new RuntimeException("渠道状态不能为空");
        }
        if(null == param.getPriceType()){
            throw new RuntimeException("价格模式不能为空");
        }
        if(null == param.getAutoOrderSwitch()){
            throw new RuntimeException("自动处理订单开关不能为空");
        }
        /// 后续再说
//        if(null == param.getAutoOrderPriceMin()){
//            throw new RuntimeException("自动处理订单价格区间最低值不能为空");
//        }
//        if(null == param.getAutoOrderPriceMax()){
//            throw new RuntimeException("自动处理订单价格区间最高值不能为空");
//        }
        if(null == param.getAccountCredit()){
            throw new RuntimeException("账户额度不能为空");
        }
        if(null == param.getMinimum()){
            throw new RuntimeException("账户额度预警不能为空");
        }
        HtRouteInfo htRouteInfo = new HtRouteInfo();
        BeanUtil.copyProperties(param, htRouteInfo);
        htRouteInfo.setRouteName(param.getUserName());
        htRouteInfo.setRouteId(param.getAppId());
        htRouteInfo.setRouteSecret(param.getSecretKey());
        htRouteInfo.setContactTel(param.getTel());
        htRouteInfo.setRouteType(param.getSellerType());
        htRouteInfo.setRouteStatus(param.getStatus());
        htRouteInfo.setContactEmail(param.getEmail());
        return htRouteInfoDao.insert(htRouteInfo) == 1 ? "新增成功!" : "新增失败!";
    }

    public String deleteRouteInfo(RemoveRouteInfoParam param){
        if(StringUtils.isBlank(param.getId())){
            throw new RuntimeException("删除主键不能为空");
        }
        return htRouteInfoDao.deleteById(Long.valueOf(param.getId())) == 1 ? "删除成功!" : "删除失败!";
    }
}
